from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.backends import default_backend
from base64 import b64encode, b64decode
import os
import json
from src.core import str_utils as str
import hashlib
from src.core import  Config


def configure_crypt_from_env():
    """
        此函数从指定的 JSON 配置文件中读取与给定日志级别类型和键相关的配置信息。

        参数:
        - level_type (str): 要查找的日志级别类型，例如 'info'、'error' 等。
        - key (str): 要获取的配置键，例如 'encryption_key' 等。

        函数执行以下操作:
        1. 获取当前脚本的目录路径。
        2. 构建配置文件的绝对路径。
        3. 打开并读取配置文件的内容为 JSON 格式。
        4. 遍历配置中的每个日志类型及其设置。
        5. 当找到启用且与给定级别类型匹配的日志设置时，获取指定键对应的值。

        返回:
        - 与给定日志级别类型和键对应的配置值，如果未找到匹配的配置则返回 None。
        """

    key_dict='ss.api.admin'
    if Config.CRYPT_ENABLED   :  # 检查是否启用该日志级别
        key_dict = Config.CRYPT_KEY

        # 加载配置文件并配置 loguru
    # 返回是否配置了日志
    return key_dict


def get_crypt_key():
    """
        此函数用于获取加密密钥。

        函数执行以下操作：
        1. 调用 `configure_crypt_from_env` 函数，从配置中获取与 "crypt" 类型和 "key" 键相关的初始密钥。
        2. 将初始密钥与其自身反转后的字符串拼接。

        返回:
        经过处理后的加密密钥字符串。
        """
    key = configure_crypt_from_env()
    key = key + str.reverse(key)
    return key


def aes_encrypt(data, key=get_crypt_key()):
    """
       此函数使用 AES 加密算法对输入的数据进行加密。

       参数:
       - data (str): 要加密的原始数据。
       - key (str, 可选): 加密使用的密钥，默认使用 `get_crypt_key` 函数获取。

       函数执行以下操作:
       1. 使用 `PKCS7` 填充方式将输入数据填充至 128 位块大小的倍数。
       2. 创建 `AES` 加密对象，使用指定的密钥和初始化向量（`IV`）。
       3. 使用创建的加密对象对填充后的数据进行加密。
       4. 将加密后的密文进行 `base64` 编码，并将编码后的结果以 `utf-8` 解码为字符串返回。

       返回:
       经过 `AES` 加密和 `base64` 编码后的字符串。
    """
    # 填充数据至块大小的倍数
    padder = padding.PKCS7(128).padder()
    padded_data = padder.update(data.encode()) + padder.finalize()

    # 创建一个cipher对象
    iv = b"\x00" * 16  # 初始化向量，通常与块大小相同（对于AES是16字节）
    cipher = Cipher(algorithms.AES(key.encode()), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    print(encryptor)

    # 加密数据
    ciphertext = encryptor.update(padded_data) + encryptor.finalize()

    # 返回base64编码的密文
    return b64encode(ciphertext).decode('utf-8')


def aes_decrypt(ciphertext, key=get_crypt_key()):
    """
        此函数用于对使用 AES 加密并经过 base64 编码的密文进行解密。

        参数:
        - ciphertext (str): 经过 base64 编码的密文字符串。
        - key (str, 可选): 解密使用的密钥，默认使用 `get_crypt_key` 函数获取。

        函数执行以下操作:
        1. 对输入的 base64 编码密文进行解码。
        2. 创建与加密时相同配置的 `AES` 解密对象，包括密钥和初始化向量（`IV`）。
        3. 使用解密对象对解码后的密文进行解密，得到填充后的明文数据。
        4. 去除填充数据，得到原始明文。

        返回:
        解密后的原始字符串。
    """
    # 解码base64编码的密文
    ciphertext = b64decode(ciphertext.encode('utf-8'))

    # 创建一个cipher对象
    iv = b"\x00" * 16  # 初始化向量，需要与加密时使用的相同
    cipher = Cipher(algorithms.AES(key.encode()), modes.CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()

    # 解密数据
    decrypted_padded_data = decryptor.update(ciphertext) + decryptor.finalize()

    # 去除填充
    unpadder = padding.PKCS7(128).unpadder()
    decrypted_data = unpadder.update(decrypted_padded_data) + unpadder.finalize()

    # 返回解密后的字符串
    return decrypted_data.decode('utf-8')

def md5(data):
    md5_hash = hashlib.md5(data.encode()).hexdigest()
    return md5_hash

if __name__ == '__main__':
    # 使用示例
    # key = "sen_shan@139.com"  # AES密钥长度通常是16（AES-128）、24（AES-192）或32（AES-256）字节
    key = configure_crypt_from_env()
    key = key + str.reverse(key)
    print(key)
    data = "dev@ssapi"
    encrypted = aes_encrypt(data, key)
    print("Encrypted:", encrypted)

    decrypted = aes_decrypt(encrypted, key)
    print("Decrypted:", decrypted)

    data = "ssapi"
    encrypted = aes_encrypt(data, key)
    print("Encrypted:", encrypted)

    decrypted = aes_decrypt(encrypted, key)
    print("Decrypted:", decrypted)

    data = "127.0.0.1"
    encrypted = aes_encrypt(data, key)
    print("Encrypted:", encrypted)

    decrypted = aes_decrypt(encrypted, key)
    print("Decrypted:", decrypted)

    data = "DEV"
    encrypted = aes_encrypt(data, key)
    print("Encrypted:", encrypted)

    decrypted = aes_decrypt(encrypted, key)
    print("Decrypted:", decrypted)

    data = "3306"
    encrypted = aes_encrypt(data, key)
    print("Encrypted:", encrypted)

    decrypted = aes_decrypt(encrypted, key)
    print("Decrypted:", decrypted)
